/**
 * 打印堆栈信息。
 */
function showStacks() {
    Java.perform(function () {
        // send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
        console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
    });
}



Java.perform(function (){
    /**
     * 通过搜索头部数据得到了 一个 函数,
     * hook该函数,打印堆栈信息,可以找到调用关系
     * 该函数返回的头部需要的数据
     */
    let header = Java.use("mtopsdk.mtop.protocol.converter.impl.InnerNetworkConverter");
    header.getHeaderConversionMap.implementation = function(){
        const res = this.getHeaderConversionMap();
        // showStacks();
        // console.log("-------------------------------getHeaderConversionMap 开始遍历...-------------------------------");
        // var resIt = res.keySet().iterator();
        // while(resIt.hasNext()){
        //     var resKey = resIt.next().toString();
        //     var resValue = res.get(resKey);
        //     console.log("key: " + resKey + "\tvalue: " +resValue
        //     );
        // }
        // console.log("-------------------------------getHeaderConversionMap 结束遍历...-------------------------------");
        return res;
    }
    /**
     * hook 加密函数  第二步走这里
     * 参数1 为map类型,携带请求数据,和头部数据
     * 参数2 的map只有两个 x-region-channel 和 x-bx-version
     * 参数3 为布尔值 false
     * @type {Java.Wrapper<{}>}
     */
    let req = Java.use("mtopsdk.mtop.protocol.converter.impl.AbstractNetworkConverter");
    req.buildRequestHeaders.implementation = function(v1,v2,v3){
        const v1key = v1.keySet();
        const v2key = v2.keySet();
        const v1It = v1key.iterator();
        const v2It = v2key.iterator();
        console.log("-------------------------------参数1 开始遍历...-------------------------------");
        //这里随机重写一个新的设备ID, 是不反回数据的,设备ID 要被激活，签入才能用
        // v1.put("deviceId","AnKpFdlJMQjYZ1t");
        // v1.put("sign","azYBCM002xAAHYZ+R4RJLABgvNcU/YZ9hsAGm4HjfsTdfeZ+c0k1uSrKZlr17jezd6LZxIMQoU61N0J51kzCOlRKV213fYZ9h32GfY");
        // var str = {"entityId":"1220","env":"1","params":"{\"context\":null,\"query\":\"农村\"}","bizVersion":"3"}
        // console.log(JSON.stringify(str));
        // v1.put("data",JSON.stringify(str))
        while(v1It.hasNext()){
            const v1KeyStr = v1It.next().toString();
            const v1ValueStr = v1.get(v1KeyStr)==null?"null":v1.get(v1KeyStr).toString();
            console.log("key: " + v1KeyStr + "\tvalue: " +v1ValueStr);
        }
        console.log("-------------------------------参数1 结束遍历...-------------------------------");
        console.log("-------------------------------参数2 开始遍历...-------------------------------");
        while(v2It.hasNext()){
            const v2KeyStr = v2It.next().toString();
            const v2ValueStr = v2.get(v2KeyStr)==null?"null":v2.get(v2KeyStr).toString();
            console.log("key: " + v2KeyStr + "\tvalue: " +v2ValueStr);
        }
        console.log("-------------------------------参数2 结束遍历...-------------------------------");
        console.log("参数3 :" + v3);
        var res = this.buildRequestHeaders(v1,v2,v3);
        console.log("-------------------------------返回值 开始遍历...-------------------------------");
        var resIt = res.keySet().iterator();
        while(resIt.hasNext()){
            var resKey = resIt.next().toString();
            var resValue = res.get(resKey);
            console.log("key: " + resKey + "\tvalue: " +resValue
            );
        }
        console.log("-------------------------------返回值 结束遍历...-------------------------------");
        return res;
    }

    /**
     * hook 验证签名算法 sign 第一步走这里
     * @type {Java.Wrapper<{}>}
     */
    let sign = Java.use("tb.lll");
    sign.a.overload('java.util.HashMap','java.util.HashMap', 'java.lang.String', 'java.lang.String', 'boolean').implementation = function(v1,v2,v3,v4,v5){
        //参数一中的 deviceId 和utdid 重写后不受影响,可以捏造
        v1.put("deviceId","AnKpFdlJMQjYZ11-YIvKNQczd9lIMnaIw_nJUk8fecd1");
        v1.put("utdid","YAHK1j73ApYDALBQDW2fij31");
        var str = {"entityId":"1220","env":"1","params":"{\"context\":null,\"query\":\"农村\"}","bizVersion":"3"}
        v1.put("data",JSON.stringify(str));
        console.log("-------------------------------sign签名 开始遍历...-------------------------------");
        // while(v1It.hasNext()){
        //     const v1KeyStr = v1It.next().toString();
        //     const v1ValueStr = v1.get(v1KeyStr)==null?"null":v1.get(v1KeyStr).toString();
        //     console.log("key: " + v1KeyStr + "\tvalue: " +v1ValueStr);
        // }
        console.log("参数1: " + v1);
        console.log("参数2: " + v2);
        console.log("参数3: " + v3);
        console.log("参数4: " + v4);
        console.log("参数5: " + v5);
        var res = this.a(v1,v2,v3,v4,v5);
        console.log("返回值为:" + res);
        console.log("-------------------------------sign签名 结束遍历...-------------------------------");
        return res;
    }
})